package com.atguigu.crowd.mvc.config;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;

import com.atguigu.crowd.constant.CrowdConstant;

//注意！这个类一定要放在自动扫描的包下，否则所有配置都不会生效！
//将当前类标记为配置类
@Configuration
//启用 Web 环境下权限控制功能
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebAppSecurityConfig extends WebSecurityConfigurerAdapter {
	
	@Autowired
	private UserDetailsService userDetailsService;
	
	@Autowired
	private BCryptPasswordEncoder passwordEncoder;
	
	/*
	 * @Bean public BCryptPasswordEncoder getPasswordEncoder() { return new
	 * BCryptPasswordEncoder(); }
	 */
	
	@Override
	protected void configure(AuthenticationManagerBuilder builder) throws Exception {
		//与 SpringSecurity 环境下用户登录相关
		builder
		.userDetailsService(userDetailsService)
		.passwordEncoder(passwordEncoder);
	}

	@Override
	protected void configure(HttpSecurity security) throws Exception {
		//与 SpringSecurity 环境下请求授权相关
		security
		.authorizeRequests()	// 对请求进行授权
		.antMatchers("/admin/to/login/page.html")	// 针对/index.jsp 路径进行授权
		.permitAll()	// 可以无条件访问
		.antMatchers("/bootstrap/**")	
		.permitAll()	
		.antMatchers("/crowd/**")	
		.permitAll()	
		.antMatchers("/css/**")	
		.permitAll()	
		.antMatchers("/fonts/**")	
		.permitAll()	
		.antMatchers("/img/**")	
		.permitAll()	
		.antMatchers("/jquery/**")	
		.permitAll()	
		.antMatchers("/layer/**")
		.permitAll()
		.antMatchers("/script/**")	
		.permitAll()	
		.antMatchers("/ztree/**")	
		.permitAll()	
		.antMatchers("/layui/**")	// 针对/layui 目录下所有资源进行授权
		.permitAll()	// 可以无条件访问
		.antMatchers("/admin/get/page.html")// 针对分页显示 Admin 数据设定访问控制
		.access("hasRole('经理') OR hasAuthority('user:get')") // 要求具备 “ 经理 ” 角色和		“user:get”权限二者之一
		.anyRequest()	// 任意请求
		.authenticated()	// 需要登录以后才可以访问
		.and()
		.exceptionHandling()
		.accessDeniedHandler(new AccessDeniedHandler() {
			@Override
			public void handle(HttpServletRequest request, HttpServletResponse response,
				AccessDeniedException	accessDeniedException)	throws	IOException,
			ServletException {
			request.setAttribute("exception",	new Exception(CrowdConstant.MESSAGE_ACCESS_DENIED));
			request.getRequestDispatcher("/WEB-INF/system-error.jsp").forward(request, response);
			}
		})
		.and()
		.csrf()
		.disable()
		.formLogin()
		.loginPage("/admin/to/login/page.html")
		.loginProcessingUrl("/security/do/login.html")
		.defaultSuccessUrl("/admin/to/main/page.html")
		.permitAll()
		.usernameParameter("loginAcct")
		.passwordParameter("userPswd")
		.and()
		.logout()
		.logoutUrl("/security/do/logout.html")
		.logoutSuccessUrl("/admin/to/login/page.html")
		;
		

	}
}
